import { Calendar, DatePicker, Empty, Input, message, Popover } from 'antd';
import { CheckRecordT, CheckT } from '../..';

import { useEffect, useMemo, useState } from 'react';
import moment, { Moment } from 'moment';
import TButton from '@/components/TButton';
import DivideLine from '@/components/Divider';
import CheckCalendar from '@/components/CheckCalendar';

import './index.less';

const { RangePicker } = DatePicker;

interface IProps {
  checkItem: CheckT;
  onEditDesc: (desc: string, record: CheckRecordT) => void;
  onReCheck: (date: string) => void;
  onCancel: (record: CheckRecordT) => void;
}

// -打卡情况
// --支持补打
// --打卡描述

// -统计
// --总打卡天数
// --已连续打卡天数
// --最大连续打卡天数

type CheckStatisticT = {
  sum: number;
  curContinuity: number;
  maxContinuity: number;
  noCheck: number;
  percent: number | string;
};

const CheckDetail = (props: IProps) => {
  const { checkItem, onEditDesc, onReCheck, onCancel } = props;
  const [activeYear, setActiveYear] = useState<moment.Moment>(moment());
  const [range, setRange] = useState<any>([]);
  const [visibleDate, setVisibleDate] = useState('');
  const [statisticData, setStatisticData] = useState<CheckStatisticT>({
    sum: 0,
    curContinuity: 0,
    maxContinuity: 0,
    noCheck: 0,
    percent: 0,
  });
  const [editTarget, setEditTarget] = useState<string>('');

  useEffect(() => {
    if (checkItem.records.length) {
      setRange([moment(checkItem.records[0].date), moment()]);
    } else {
      setRange([]);
    }
    setEditTarget('');
  }, [checkItem]);

  useEffect(() => {
    calc();
  }, [checkItem, range]);

  const handleReCheck = (date: Moment) => {
    setVisibleDate('');
    setTimeout(() => {
      onReCheck(date.toISOString());
    });
  };

  const calc = () => {
    if (!checkItem.records.length) {
      setStatisticData({
        sum: 0,
        maxContinuity: 0,
        curContinuity: 0,
        percent: 0,
        noCheck: 0,
      });
      return;
    }

    const { records } = checkItem;
    const endDay = records[records.length - 1];
    let calcDay = moment(endDay.date);
    let curCount = 0; // 代表当前连续打卡天数
    let curOver = false; // true时不再累计
    let maxCount = 0; // 连续打卡天数计数器
    let max = 0; // 最大连续值
    for (let i = records.length - 1; i >= 0; i--) {
      const m = moment(records[i].date);
      if (calcDay.isSame(m, 'day')) {
        calcDay.subtract(1, 'day');
        if (!curOver) {
          curCount++;
        }
        maxCount++;
      } else {
        if (!curOver) {
          curOver = true;
        }
        max = Math.max(max, maxCount);
        maxCount = 1;
        calcDay = moment(records[i].date);
        calcDay.subtract(1, 'day');
      }
    }
    max = Math.max(max, maxCount);

    // 计算未打卡天数与打卡率需要range范围
    if (!range.length) {
      setStatisticData({
        sum: records.length,
        maxContinuity: max,
        curContinuity: curCount,
        percent: 0,
        noCheck: 0,
      });
      return;
    }

    const rangeEnd = range[1];
    let calcTarget = moment(range[0].toISOString());
    let unCheckCount = 0;
    let checkedCount = 0;
    const checkStrList = checkItem.records.map((i) =>
      moment(i.date).format('YYYY-MM-DD'),
    );
    while (calcTarget.isSameOrBefore(rangeEnd)) {
      const calcDayString = calcTarget.format('YYYY-MM-DD');
      if (!checkStrList.includes(calcDayString)) {
        unCheckCount++;
      } else {
        checkedCount++;
      }
      calcTarget.add(1, 'day');
    }
    setStatisticData({
      sum: records.length,
      maxContinuity: max,
      curContinuity: curCount,
      percent:
        checkedCount + unCheckCount === 0
          ? 0
          : ((checkedCount / (checkedCount + unCheckCount)) * 100).toFixed(2) +
            '%',
      noCheck: unCheckCount,
    });
  };

  const renderDateCell = (m: Moment) => {
    let checkFlag = false;
    for (const i of checkItem.records) {
      if (m.isSame(moment(i.date), 'day')) {
        checkFlag = true;
        break;
      }
    }
    const className = checkFlag
      ? 'check-date-cell check-date-cell__checked'
      : 'check-date-cell';
    return <div className={className}>{m.date()}</div>;
  };

  const renderRecordDetail = (m: Moment, dateStr: string) => {
    const record =
      checkItem.records.find((i) => {
        return moment(i.date).format('YYYY-MM-DD') === dateStr;
      }) || null;

    if (record) {
      const m = moment(record.date);
      return (
        <div>
          <div style={{ margin: '6px 0' }}>
            <label style={{ width: '100px' }}>打卡时间：</label>
            <span>{`${m.format('Y-M-D HH:mm')}`}</span>
          </div>
          <div className="container">
            <label style={{ width: '100px' }}>打卡描述：</label>
            <Input.Search
              key={record.date}
              placeholder="输入打卡描述"
              allowClear
              enterButton="确认"
              size="small"
              defaultValue={record.desc || ''}
              onSearch={(v) => {
                onEditDesc(v, record);
                setVisibleDate('');
              }}
            />
          </div>
          <TButton
            danger
            style={{ width: '100%', marginTop: '10px' }}
            onClick={() => {
              setVisibleDate('');
              setTimeout(() => {
                onCancel(record);
              });
            }}
          >
            取消打卡
          </TButton>
        </div>
      );
    } else {
      return (
        <div>
          <div>无打卡记录</div>
          {m.isBefore(moment()) && (
            <TButton
              onClick={() => {
                handleReCheck(m);
              }}
              style={{ marginTop: '10px' }}
              fullWidth
            >
              补卡
            </TButton>
          )}
        </div>
      );
    }
  };

  const renderHistory = () => {
    if (!range.length) {
      return <></>;
    }
    const checkCalendarConfig = checkItem.records.map((i) => ({
      dataStr: moment(i.date).format('YYYY-MM-DD'),
      moment: moment(i.date),
    }));
    return (
      <CheckCalendar
        activeYear={activeYear.year()}
        dateRange={range}
        checkList={checkCalendarConfig}
        selected={editTarget}
        onSelect={(i) => {
          setEditTarget(i);
        }}
        canvas={false}
      />
    );
  };

  const renderStatistics = () => {
    const config = [
      {
        key: 'sum',
        name: '总打卡天数',
      },
      {
        key: 'curContinuity',
        name: '当前连续打卡天数',
      },
      {
        key: 'maxContinuity',
        name: '最大连续打卡天数',
      },
      {
        key: 'noCheck',
        name: '未打卡天数',
      },
      {
        key: 'percent',
        name: '打卡率',
      },
    ] as { key: keyof CheckStatisticT; name: string }[];

    return (
      <div className="check-statistics">
        {config.map((i) => (
          <div className="check-statistics__item" key={i.key}>
            <div className="check-statistics__name">{i.name}</div>
            <div className="check-statistics__value">
              {statisticData?.[i.key] || 0}
            </div>
          </div>
        ))}
      </div>
    );
  };

  return (
    <div className="check-detail">
      <div className="check-records__container">
        <div className="base-padding" style={{ marginBottom: '4px' }}>
          <h3 className="check-records__title">打卡记录</h3>
          <div>
            <label style={{ marginRight: '6px' }}>记录范围:</label>
            <DatePicker
              size="small"
              value={activeYear}
              allowClear={false}
              onChange={(value) => {
                if (!value?.year()) {
                  message.warn('年份选择异常');
                  return;
                }
                setActiveYear(value);
              }}
              picker="year"
            />
            <span style={{ margin: '0 10px' }}>年</span>
            <RangePicker
              value={range}
              size="small"
              allowClear={false}
              disabledDate={(date) => {
                return !date.isSame(
                  moment(`${activeYear.year()}-01-01`),
                  'year',
                );
              }}
              format="MM/DD"
              onChange={(dates) => {
                const range =
                  dates?.map((i) => {
                    return moment(i?.toISOString());
                  }) || [];
                setRange(range);
              }}
            />
          </div>
          {range.length ? (
            <>
              <div className="check-records__history">{renderHistory()}</div>
              {editTarget && (
                <>
                  <DivideLine bottom={10} />

                  {renderRecordDetail(moment(editTarget), editTarget)}
                </>
              )}
            </>
          ) : (
            <Empty />
          )}
        </div>
        <DivideLine />
        <div className="base-padding" style={{ marginBottom: '4px' }}>
          <h3 className="check-records__title">打卡统计</h3>
          {renderStatistics()}
        </div>
        <DivideLine />
        <div className="base-padding" style={{ marginBottom: '4px' }}>
          <h3 className="check-records__title">打卡日历</h3>
          <Calendar fullscreen={false} dateFullCellRender={renderDateCell} />
        </div>
      </div>
    </div>
  );
};

export default CheckDetail;
